/*-------------------------------------------------------------------------
 *
 * pg_sema.h
 *	  跨平台的信号量 API。
 *
 * PostgreSQL 需要计数信号量（用于跟踪多个解锁操作，并允许在阻塞之前进行相等数量的后续锁定操作）。底层实现不是在每个平台上都相同。此文件定义了每个端口必须提供的 API。
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/storage/pg_sema.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef PG_SEMA_H
#define PG_SEMA_H

/*
 * struct PGSemaphoreData 和指针类型 PGSemaphore 是表示
 * 单个信号量的数据结构。PGSemaphoreData 的内容在
 * 各个实现中不同，绝不能被平台无关的代码触碰；
 * 因此，PGSemaphoreData 在这里声明为一个不透明结构。
 *
 * 然而，Windows 与我们其他端口的差异足够大，似乎不值得
 * 对 Windows 也坚持 ABI 兼容性。因此，在该平台上将
 * PGSemaphore 定义为 HANDLE。
 */
#ifndef USE_WIN32_SEMAPHORES
typedef struct PGSemaphoreData *PGSemaphore;
#else
typedef HANDLE PGSemaphore;
#endif


/* 报告所需的共享内存量 */
extern Size PGSemaphoreShmemSize(int maxSemas);

/* 模块初始化（在 postmaster 启动或 shmem 重新初始化期间调用） */
extern void PGReserveSemaphores(int maxSemas);

/* 分配一个初始计数为 1 的 PGSemaphore 结构 */
extern PGSemaphore PGSemaphoreCreate(void);

/* 将之前初始化的 PGSemaphore 重置为计数为 0 */
extern void PGSemaphoreReset(PGSemaphore sema);

/* 锁定信号量（递减计数），如果计数小于 0 则阻塞 */
extern void PGSemaphoreLock(PGSemaphore sema);

/* 解锁信号量（递增计数） */
extern void PGSemaphoreUnlock(PGSemaphore sema);

/* 仅在能够不阻塞的情况下锁定信号量 */
extern bool PGSemaphoreTryLock(PGSemaphore sema);

#endif							/* PG_SEMA_H */
